﻿using System.ComponentModel;
using System.Diagnostics;
using System.Windows;

namespace PrjUIExDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private BackgroundWorker worker;

        public MainWindow()
        {
            InitializeComponent();

            List<TreeViewModel> viewModels = new List<TreeViewModel>();

            for (int i = 0; i < 10; i++)
            {
                TreeViewModel viewModel = new TreeViewModel();
                viewModel.Parent = null;
                viewModel.IsChecked = false;
                viewModel.Name = $"{i}";
                viewModel.Visibility = Visibility.Visible;

                for (int j = 0; j < 10; j++)
                {
                    TreeViewModel viewModelTemp = new TreeViewModel();
                    viewModelTemp.Parent = viewModel;
                    viewModelTemp.IsChecked = false;
                    viewModelTemp.Name = $"{i}-{j}";
                    viewModelTemp.Visibility = Visibility.Collapsed;
                    viewModel.Children.Add(viewModelTemp);
                }

                viewModels.Add(viewModel);
            }

            this.tv.ItemsSource = viewModels;

            worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += Worker_DoWork;
            worker.ProgressChanged += Worker_ProgressChanged;
            worker.RunWorkerCompleted += Worker_RunWorkerCompleted;

        }

        private void Worker_RunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                MessageBox.Show(e.Cancelled.ToString());
            }
            else if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else
            {
                BackgroundWorkerItem workerItem = e.Result as BackgroundWorkerItem;
                if (workerItem != null)
                {
                    this.txtPro.Text = workerItem.Index.ToString();
                    this.txt.Text = workerItem.DateTimeCur.ToString();
                }
            }
        }

        private void Worker_ProgressChanged(object? sender, ProgressChangedEventArgs e)
        {
            this.txtPro.Text = e.ProgressPercentage.ToString();
            mbar.SelectedIndex = e.ProgressPercentage % 5;
        }

        private void Worker_DoWork(object? sender, DoWorkEventArgs e)
        {
            BackgroundWorkerArgument WorkAction = e.Argument as BackgroundWorkerArgument;

            for (int j = 0; j < 10; j++)
            {
                if (worker.CancellationPending)
                {
                    return;
                }

                Thread.Sleep(2000);
                if (worker.WorkerReportsProgress)
                {
                    int ret = WorkAction.WorkAction.Invoke(j);
                    worker.ReportProgress(ret);
                }
            }

            Thread.Sleep(2000);
            BackgroundWorkerItem workerItem = new BackgroundWorkerItem();
            workerItem.Index = 10;
            workerItem.DateTimeCur = DateTime.Now;
            e.Result = workerItem;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //Thread thread = new Thread(UpdateTxtContext);
            //thread.Start();
            worker.RunWorkerAsync(new BackgroundWorkerArgument((int i) =>
            {
                return 100 + i;
            }));
        }

        private void UpdateTxtContext()
        {
            var opt = this.Dispatcher.BeginInvoke(() =>
              {
                  Thread.Sleep(2000);
                  this.txt.Text = DateTime.Now.ToString();
              });

            Debug.WriteLine(opt.Status);
        }
    }

    public class BackgroundWorkerItem
    {
        public int Index { get; set; }
        public DateTime DateTimeCur { get; set; }

    }

    public class BackgroundWorkerArgument
    {
        public Func<int, int> WorkAction { get; set; }

        public BackgroundWorkerArgument(Func<int, int> workAction) { this.WorkAction = workAction; }
    }
}